added SSCLI 1.0
[windows-sources.git] / shared source / wpf / src / host / shimimpl / applicationmanifest.cxx
blob2ba1139d72ccf68e5a4b1aaec9dc2694451ee88e
1 //------------------------------------------------------------------------
2 //
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 //
5 // Description:
6 // Implements the interface to the application manifest
7 //
8 // History:
9 // 2005/05/09 - [....] Created
10 // 2007/09/20 [....] Ported Windows->DevDiv. See SourcesHistory.txt.
12 //------------------------------------------------------------------------
14 #include "PreCompiled.hxx"
15 #include "ApplicationManifest.hxx"
17 #define KEY_ASSEMBLY L"WindowsBase"
18 #define REQUESTED_CLR L"Microsoft.Windows.CommonLanguageRuntime"
21 CApplicationManifest::CApplicationManifest(__in LPCWSTR pswzUri, __in LPCWSTR pswzCodebase)
23 SetDeploymentManifestUri(pswzUri);
24 SetCodebase(pswzCodebase);
25 m_refCount = 0;
26 m_pInternetSecurityManager = NULL;
27 m_dwDeploymentManifestZone = 0;
30 STDMETHODIMP CApplicationManifest::QueryInterface(const struct _GUID &riid,void ** ppvObject)
32 *ppvObject = NULL;
34 if (riid == IID_IUnknown)
36 *ppvObject = static_cast<ISAXContentHandler *>(this);
38 else if (riid == __uuidof(ISAXContentHandler))
40 *ppvObject = static_cast<ISAXContentHandler *>(this);
42 else if (riid == __uuidof(IBindStatusCallback))
44 *ppvObject = static_cast<IBindStatusCallback *>(this);
47 if (*ppvObject)
49 AddRef();
50 return S_OK;
52 else
54 return E_NOINTERFACE;
58 STDMETHODIMP_(DWORD) CApplicationManifest::AddRef()
60 return InterlockedIncrement(&m_refCount);
63 STDMETHODIMP_(DWORD) CApplicationManifest::Release()
65 InterlockedDecrement(&m_refCount);
66 if (m_refCount == 0)
68 delete this;
69 return 0;
71 else
73 return m_refCount;
77 IFACEMETHODIMP CApplicationManifest::startElement(
78 __in_ecount(cchNamespaceUri) const wchar_t *pwchNamespaceUri,
79 __in int cchNamespaceUri,
80 __in_ecount(cchLocalName) const wchar_t *pwchLocalName,
81 __in int cchLocalName,
82 __in_ecount(cchQName) const wchar_t *pwchQName,
83 __in int cchQName,
84 __in ISAXAttributes *pAttributes)
86 HRESULT hr = S_OK;
88 const UINT BUFFER_LENGTH = 1024;
89 LPCWSTR pwzValue;
91 if (wcscmp(pwchLocalName, L"assemblyIdentity") == 0)
93 int nLength = BUFFER_LENGTH;
94 CKHR(pAttributes->getValueFromName(L"", 0, L"name", 4, &pwzValue, &nLength));
95 if (wcscmp(pwzValue, KEY_ASSEMBLY) == 0)
97 CKHR(pAttributes->getValueFromName(L"", 0, L"version", 7, &pwzValue, &nLength));
98 SetRequestedVersion(pwzValue);
100 else if (wcscmp(pwzValue, REQUESTED_CLR) == 0)
102 CKHR(pAttributes->getValueFromName(L"", 0, L"version", 7, &pwzValue, &nLength));
103 SetRequestedClrVersion(pwzValue);
106 if (GetRequestedVersion() != NULL && GetRequestedClrVersion() != NULL)
108 CKHR(E_FAIL); // Stop parsing when we have both manifests
112 Cleanup:
113 return hr;
116 HRESULT CApplicationManifest::Read()
118 HRESULT hr = S_OK;
119 ISAXXMLReader* pReader = NULL;
121 // Resolve the deployment manifest URI with the application manifest codebase
122 WCHAR wzAppManUri[INTERNET_MAX_URL_LENGTH + 1];
123 DWORD dwLength = 0;
124 CKHR(CoInternetCombineUrl(
125 GetDeploymentManifestUri(),
126 GetCodebase(),
128 wzAppManUri,
129 INTERNET_MAX_URL_LENGTH,
130 &dwLength,
131 0));
133 CKHR(SetUri(wzAppManUri));
135 EventWriteWpfHostUm_ReadingAppManifestStart(wzAppManUri);
137 // cocreate the pointer to the COM interface we require
138 // CLSID for internet security managed "7b8a2d94-0ac9-11d1-896c-00c04Fb6bfc4"
139 // GUID for the interface we want to extract "79eac9ee-baf9-11ce-8c82-00aa004ba90b"
140 CKHR(CoCreateInstance(CLSID_InternetSecurityManager,
141 NULL, CLSCTX_INPROC_SERVER,
142 IID_IInternetSecurityManager,
143 (void **)&m_pInternetSecurityManager));
145 // Compare zones
146 m_dwDeploymentManifestZone = 0;
147 CKHR(m_pInternetSecurityManager->MapUrlToZone(GetDeploymentManifestUri(), &m_dwDeploymentManifestZone, 0));
149 DWORD dwApplicationManifestZone = 0;
150 CKHR(m_pInternetSecurityManager->MapUrlToZone(GetUri(), &dwApplicationManifestZone, 0));
152 // Manifests must both come from the same zone. This is ClickOnce behavior, and we want
153 // to be consistent with it.
154 CKHR(m_dwDeploymentManifestZone == dwApplicationManifestZone ? S_OK : E_FAIL);
156 // Download the file. The IBindStatusCallback::Progress method will get the new redirected URI,
157 // and do zone matching there.
158 WCHAR wzCacheFileName[MAX_PATH];
159 // Note: URLDownloadToCacheFile's 4th param is number of characters, not number of bytes as
160 // stated in the SDK.
161 CKHR(URLDownloadToCacheFile(NULL, GetUri(), wzCacheFileName, MAX_PATH, 0, this));
163 CKHR(CoCreateInstance(__uuidof(SAXXMLReader), NULL, CLSCTX_INPROC_SERVER, __uuidof(ISAXXMLReader), (void**)&pReader));
164 CKHR(pReader->putContentHandler(this));
165 hr = pReader->parseURL(wzCacheFileName);
167 // If we stopped the parse because we found the version, hr will be E_FAIL and
168 // the version will be set in the manifest.
169 if (hr == E_FAIL && GetRequestedVersion() != NULL)
171 hr = S_OK;
174 EventWriteWpfHostUm_ReadingAppManifestEnd();
176 Cleanup:
177 SAFERELEASE_POINTER(pReader);
178 SAFERELEASE_POINTER(m_pInternetSecurityManager);
180 return hr;
183 HRESULT CApplicationManifest::GetBindInfo(__in DWORD*, __inout BINDINFO* pBindInfo)
185 //!!! Make sure to set BINDINFO_OPTIONS_ENABLE_UTF8 in all implementations of IBindStatusCallback.
186 //!!! It is needed for correct encoding of non-ASCII characters in URL paths, per RFC 3986 & 3987.
187 pBindInfo->dwOptions = BINDINFO_OPTIONS_ENABLE_UTF8;
188 return S_OK;
191 HRESULT CApplicationManifest::OnProgress(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
193 HRESULT hr = S_OK;
195 if (ulStatusCode == BINDSTATUS_REDIRECTING)
197 SetUri(szStatusText);
198 DWORD dwApplicationManifestZone = 0;
199 CKHR(m_pInternetSecurityManager->MapUrlToZone(GetUri(), &dwApplicationManifestZone, 0));
201 // If the zones mismatch, we will stop the download immediately.
202 CKHR(m_dwDeploymentManifestZone == dwApplicationManifestZone ? S_OK : E_FAIL);
205 Cleanup:
206 return hr;